//
//  GCDConceptViewController.m
//  多线程编程
//
//  Created by Guo Rui on 2017/7/14.
//  Copyright © 2017年 GR Harry. All rights reserved.
//

#import "GCDConceptViewController.h"

@interface GCDConceptViewController ()

@end

@implementation GCDConceptViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    [self test];
}

- (void)dispatch_apply {
    /*
     用于并发迭代。
     
     如果每次迭代执行的任务与其它迭代独立无关，而且循环迭代执行顺序也无关紧要的话，你可以调用 dispatch_apply 或 dispatch_apply_f 函数来替换循环。
     
     需要注意：这两个函数会阻塞当前线程，而且和普通 for 循环一样，dispatch_apply 和 dispatch_apply_f 函数也是在所有迭代完成之后才会返回。所以如果你传递的参数是串行 queue，而且正是执行当前代码的 Queue, 就会产生死锁。主线程中调用这两个函数必须小心，可能会阻止事件处理循环并无法响应用户事件。
     */
    dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
    
    dispatch_apply(10, queue, ^(size_t index) {
        NSLog(@"%zd", index);
    });
}

// 串行队列
- (void)serialQueue {
    dispatch_queue_t queue = dispatch_queue_create("test.serialQueue", DISPATCH_QUEUE_SERIAL);
    
    NSLog(@"调度线程：%@", [NSThread currentThread]);
    
    // 添加多个异步任务
    dispatch_async(queue, ^{
        sleep(.5);
        NSLog(@"任务一");
        NSLog(@"任务一%@", [NSThread currentThread]);
    });
    
    dispatch_async(queue, ^{
        sleep(.5);
        NSLog(@"任务二");
        NSLog(@"任务二%@", [NSThread currentThread]);
        
        /*
         // 线程死锁
         dispatch_sync(queue, ^{
         sleep(.5);
         
         NSLog(@"任务五");
         NSLog(@"任务五%@", [NSThread currentThread]);
         });
         
         NSLog(@"---------任务二--------");
         */
    });
    
    dispatch_async(queue, ^{
        sleep(.5);
        NSLog(@"任务三");
        NSLog(@"任务三%@", [NSThread currentThread]);
    });
    
    dispatch_async(queue, ^{
        sleep(.5);
        NSLog(@"任务四");
        NSLog(@"任务四%@", [NSThread currentThread]);
    });
}

// 并发队列
- (void)concurrentQueue {
    
    dispatch_queue_t queue = dispatch_queue_create("test.concurrentQueue", DISPATCH_QUEUE_CONCURRENT);
    
    NSLog(@"调度线程：%@", [NSThread currentThread]);
    
    // 添加多个任务
    dispatch_async(queue, ^{
        sleep(.5);
        NSLog(@"任务一");
        NSLog(@"任务一%@", [NSThread currentThread]);
        
        dispatch_sync(queue, ^{
            sleep(.5);
            NSLog(@"任务五");
            NSLog(@"任务五%@", [NSThread currentThread]);
        });
        
        NSLog(@"-------任务一---------");
    });
    
    dispatch_sync(queue, ^{
        sleep(.5);
        NSLog(@"任务二");
        NSLog(@"任务二%@", [NSThread currentThread]);
        
        dispatch_sync(queue, ^{
            sleep(.5);
            NSLog(@"任务六");
            NSLog(@"任务六%@", [NSThread currentThread]);
        });
        
        NSLog(@"-------任务二---------");
        
    });
    
    dispatch_async(queue, ^{
        sleep(.5);
        NSLog(@"任务三");
        NSLog(@"任务三%@", [NSThread currentThread]);
    });
    
    dispatch_sync(queue, ^{
        sleep(.5);
        NSLog(@"任务四");
        NSLog(@"任务四%@", [NSThread currentThread]);
    });
    
}

- (void)test{
    dispatch_queue_t queue = dispatch_queue_create("com.hao123.www", DISPATCH_QUEUE_SERIAL);
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        dispatch_sync(queue, ^{
            NSLog(@"11 %@",[NSThread currentThread]);
        });
    });
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        dispatch_sync(queue, ^{
            NSLog(@"22 %@",[NSThread currentThread]);
        });
    });
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
//        [NSThread sleepForTimeInterval:4];
        dispatch_sync(queue, ^{
            NSLog(@"33 %@",[NSThread currentThread]);
        });
    });
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        dispatch_sync(queue, ^{
            NSLog(@"44 %@",[NSThread currentThread]);
        });
    });
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        dispatch_sync(queue, ^{
            NSLog(@"55 %@",[NSThread currentThread]);
        });
    });
}

@end
